<?php

/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/8/31
 * Time: 10:04
 */
class PersonGetMsgStrategy extends DefaultGetMsgStrategy
{
    protected function getCallList()
    {
        $items = array();
        $type = MsggItem::TYPE_CALL;
        $limit = $this->limit;
        $status = array(MsggItem::STATUS_WAITING, MsggItem::STATUS_RETRYING);
        $command = MsggItem::model()->getDbConnection()->createCommand();
        $command->select(array('pid'));
        $command->from(MsggItem::model()->tableName());
        $command->andWhere('status in (' . implode(',', $status) . ')');
        $command->andwhere('type =:type', [':type' => $type]);
        $command->group = 'pid';
        $command->limit = $limit;
        //for find person who has call to send
        $pidRows = $command->queryAll();
        foreach ($pidRows as $data) {
            $pid = $data['pid'];
            $person = AlarmPerson::model()->findByPk($pid);
            $minuteSum = 0;
            if (!empty($person)) {
                $minuteSum = MsggItemValve::getTotalsByDuration($person->phone, MsggItem::TYPE_CALL, MsggItemValve::DURATION_MINUTE);
            }
            if ($pid != 0 && $minuteSum == 0) {
                //every one only send one in one time
                $msgitem = MsggItem::model()->findByAttributes(array(
                    'status' => array(
                        MsggItem::STATUS_WAITING,
                        MsggItem::STATUS_RETRYING
                    ),
                    'type' => $type,
                    'pid' => $pid,
                ), array('limit' => 1, 'order' => 'level DESC , time'));
                if (!empty($msgitem)) {
                    $items[] = $msgitem;
                }
            }
        }
        if (count($items) < $limit) {
            $msgitems = MsggItem::model()->findAllByAttributes(array(
                'status' => array(
                    MsggItem::STATUS_WAITING,
                    MsggItem::STATUS_RETRYING
                ),
                'type' => $type,
                'pid' => 0,
            ), array('limit' => $limit - count($items), 'order' => 'level DESC , time'));
            if (!empty($msgitems)) {
                $items = array_merge($items, $msgitems);
            }
        }

        return $items;
    }

    protected function getSmsList()
    {
        $items = array();
        $type = MsggItem::TYPE_SMS;
        $limit = $this->limit;
        $status = array(MsggItem::STATUS_WAITING, MsggItem::STATUS_RETRYING);
        $command = MsggItem::model()->getDbConnection()->createCommand();
        $command->select(array('pid'));
        $command->from(MsggItem::model()->tableName());
        $command->andWhere('status in (' . implode(',', $status) . ')');
        $command->andwhere('type =:type', [':type' => $type]);
        $command->group = 'pid';
        $command->limit = $limit;
        //for find person who has call to send
        $pidRows = $command->queryAll();
        foreach ($pidRows as $data) {
            $pid = $data['pid'];
            if ($pid != 0) {
                $person = AlarmPerson::model()->findByPk($pid);
                //every one only send one in one time
                $residue = $person->getResidue($type);;
                $msgitems = MsggItem::model()->findAllByAttributes(array(
                    'status' => array(
                        MsggItem::STATUS_WAITING,
                        MsggItem::STATUS_RETRYING
                    ),
                    'type' => $type,
                    'pid' => $pid,
                ), array('limit' => $residue, 'order' => 'level DESC , time'));
                if (!empty($msgitems)) {
                    $items = array_merge($items, $msgitems);
                }
            }
        }
        if (count($items) < $limit) {
            $msgitems = MsggItem::model()->findAllByAttributes(array(
                'status' => array(
                    MsggItem::STATUS_WAITING,
                    MsggItem::STATUS_RETRYING
                ),
                'type' => $type,
                'pid' => 0,
            ), array('limit' => $limit - count($items), 'order' => 'level DESC , time'));
            if (!empty($msgitems)) {
                $items = array_merge($items, $msgitems);
            }
        }
        return $items;
    }

    protected function defaultGetList()
    {
        $items = array();
        $type = $this->type;
        $limit = $this->limit;
        $status = array(MsggItem::STATUS_WAITING, MsggItem::STATUS_RETRYING);
        $command = MsggItem::model()->getDbConnection()->createCommand();
        $command->select(array('pid'));
        $command->from(MsggItem::model()->tableName());
        $command->andWhere('status in (' . implode(',', $status) . ')');
        $command->andwhere('type =:type', [':type' => $type]);
        $command->andwhere('pid !=:pid', [':pid' => 0]);
        $command->group = 'pid';
        $command->limit = $limit;
        //for find person who has mail to send
        $pidRows = $command->queryAll();
        foreach ($pidRows as $data) {
            $pid = $data['pid'];
            $person = AlarmPerson::model()->findByPk($pid);
            $maxPersonMail = $person->getResidue($type);
            if (!empty($person)) {
                $connection = Yii::app()->db;
                $sql = '';
                $sql .= 'select min(i.`id`) AS id';
                $sql .= ' from msgg_item i , alarm_item a , alarm_type t ';
                $sql .= ' where i.`status` in (' . implode(',', $status) . ')' . " AND i.`type` ='$type' AND  i.`aid` =  a.`id` AND a.`tid` = t.`id` AND i.`pid`=" . $person->id;
                $sql .= ' group by  t.`id` ';
                $sql .= ' order by i.`level` DESC , i.`time`';
                $sql .= (' limit ' . $maxPersonMail);
                //msg ids
                $command = $connection->createCommand($sql);
                $mids = $command->queryAll();
                $mids = array_column($mids, 'id');
                $msgitems = MsggItem::model()->findAllByAttributes(['id' => $mids]);
                if (!empty($msgitems)) {
                    $items = array_merge($items, $msgitems);
                }
                $residue = $maxPersonMail - count($mids);
                $msgitems = MsggItem::model()->findAllByAttributes(array(
                    'status' => array(
                        MsggItem::STATUS_WAITING,
                        MsggItem::STATUS_RETRYING
                    ),
                    'type' => $type,
                    'pid' => $pid,
                    'aid' => 0
                ), array('limit' => $residue, 'order' => 'level DESC , time'));
                if (!empty($msgitems)) {
                    $items = array_merge($items, $msgitems);
                }
            }
        }
        if (count($items) < $limit) {
            $msgitems = MsggItem::model()->findAllByAttributes(array(
                'status' => array(
                    MsggItem::STATUS_WAITING,
                    MsggItem::STATUS_RETRYING
                ),
                'type' => $type,
                'pid' => 0,
            ), array('limit' => $limit - count($items), 'order' => 'level DESC , time'));
            if (!empty($msgitems)) {
                $items = array_merge($items, $msgitems);
            }
        }
        return $items;
    }
}